extern "C" {
    fn printf(_: *const i8, _: ...) -> i32;
    fn rand() -> i32;
    fn srand(__seed: u32);
    fn time(__timer: *mut time_t) -> time_t;
    fn pow(_: f64, _: f64) -> f64;
    fn genann_init(inputs: i32, hidden_layers: i32, hidden: i32, outputs: i32) -> *mut genann;
    fn genann_randomize(ann: *mut genann);
    fn genann_copy(ann: *const genann) -> *mut genann;
    fn genann_free(ann: *mut genann);
    fn genann_run(ann: *const genann, inputs: *const f64) -> *const f64;
}
pub type __time_t = i64;
pub type time_t = __time_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct genann {
    pub inputs: i32,
    pub hidden_layers: i32,
    pub hidden: i32,
    pub outputs: i32,
    pub activation_hidden: genann_actfun,
    pub activation_output: genann_actfun,
    pub total_weights: i32,
    pub total_neurons: i32,
    pub weight: *mut f64,
    pub output: *mut f64,
    pub delta: *mut f64,
}
pub type genann_actfun = Option<unsafe extern "C" fn(*const genann, f64) -> f64>;
fn main_0(mut _argc: i32, mut _argv: *mut *mut i8) -> i32 {
    (unsafe { printf(b"GENANN example 2.\n\0" as *const u8 as *const i8) });
    (unsafe {
        printf(
            b"Train a small ANN to the XOR function using random search.\n\0" as *const u8
                as *const i8,
        )
    });
    (unsafe { srand(time(std::ptr::null_mut::<time_t>()) as u32) });
    let input: [[f64; 2]; 4] = [
        [0 as i32 as f64, 0 as i32 as f64],
        [0 as i32 as f64, 1 as i32 as f64],
        [1 as i32 as f64, 0 as i32 as f64],
        [1 as i32 as f64, 1 as i32 as f64],
    ];
    let output: [f64; 4] = [
        0 as i32 as f64,
        1 as i32 as f64,
        1 as i32 as f64,
        0 as i32 as f64,
    ];
    let mut i: i32 = 0;
    let mut ann: *mut genann = unsafe { genann_init(2 as i32, 1 as i32, 2 as i32, 1 as i32) };
    let mut err: f64 = 0.;
    let mut last_err: f64 = 1000 as i32 as f64;
    let mut count: i32 = 0 as i32;
    loop {
        count += 1;
        if count % 1000 as i32 == 0 as i32 {
            (unsafe { genann_randomize(ann) });
            last_err = 1000 as i32 as f64;
        }
        let mut save: *mut genann = unsafe { genann_copy(ann) };
        i = 0 as i32;
        while i < (unsafe { (*ann).total_weights }) {
            (unsafe {
                *((*ann).weight).offset(i as isize) +=
                    rand() as f64 / 2147483647 as i32 as f64 - 0.5f64
            });
            i += 1;
        }
        err = 0 as i32 as f64;
        err += unsafe {
            pow(
                *genann_run(ann, (input[0 as i32 as usize]).as_ptr()) - output[0 as i32 as usize],
                2.0f64,
            )
        };
        err += unsafe {
            pow(
                *genann_run(ann, (input[1 as i32 as usize]).as_ptr()) - output[1 as i32 as usize],
                2.0f64,
            )
        };
        err += unsafe {
            pow(
                *genann_run(ann, (input[2 as i32 as usize]).as_ptr()) - output[2 as i32 as usize],
                2.0f64,
            )
        };
        err += unsafe {
            pow(
                *genann_run(ann, (input[3 as i32 as usize]).as_ptr()) - output[3 as i32 as usize],
                2.0f64,
            )
        };
        if err < last_err {
            (unsafe { genann_free(save) });
            last_err = err;
        } else {
            (unsafe { genann_free(ann) });
            ann = save;
        }
        if !(err > 0.01f64) {
            break;
        }
    }
    (unsafe {
        printf(
            b"Finished in %d loops.\n\0" as *const u8 as *const i8,
            count,
        )
    });
    (unsafe {
        printf(
            b"Output for [%1.f, %1.f] is %1.f.\n\0" as *const u8 as *const i8,
            input[0 as i32 as usize][0 as i32 as usize],
            input[0 as i32 as usize][1 as i32 as usize],
            *genann_run(ann, (input[0 as i32 as usize]).as_ptr()),
        )
    });
    (unsafe {
        printf(
            b"Output for [%1.f, %1.f] is %1.f.\n\0" as *const u8 as *const i8,
            input[1 as i32 as usize][0 as i32 as usize],
            input[1 as i32 as usize][1 as i32 as usize],
            *genann_run(ann, (input[1 as i32 as usize]).as_ptr()),
        )
    });
    (unsafe {
        printf(
            b"Output for [%1.f, %1.f] is %1.f.\n\0" as *const u8 as *const i8,
            input[2 as i32 as usize][0 as i32 as usize],
            input[2 as i32 as usize][1 as i32 as usize],
            *genann_run(ann, (input[2 as i32 as usize]).as_ptr()),
        )
    });
    (unsafe {
        printf(
            b"Output for [%1.f, %1.f] is %1.f.\n\0" as *const u8 as *const i8,
            input[3 as i32 as usize][0 as i32 as usize],
            input[3 as i32 as usize][1 as i32 as usize],
            *genann_run(ann, (input[3 as i32 as usize]).as_ptr()),
        )
    });
    (unsafe { genann_free(ann) });
    return 0 as i32;
}
pub fn main() {
    let mut args: Vec<*mut i8> = Vec::new();
    for arg in ::std::env::args() {
        args.push(
            (::std::ffi::CString::new(arg))
                .expect("Failed to convert argument into CString.")
                .into_raw(),
        );
    }
    args.push(::core::ptr::null_mut());
    {
        ::std::process::exit(
            main_0((args.len() - 1) as i32, args.as_mut_ptr() as *mut *mut i8) as i32,
        )
    }
}
